package com.app.oral.controller

import com.app.oral.config.ApiResponse
import com.app.oral.dto.*
import com.app.oral.model.ExamPaper
import com.app.oral.model.PaperType
import com.app.oral.service.ExamPaperService
import com.app.oral.service.WeChatCloudStorageService
import org.slf4j.LoggerFactory
import org.springframework.web.bind.annotation.*
import org.springframework.web.multipart.MultipartFile
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
import io.swagger.v3.oas.annotations.responses.ApiResponse as SwaggerApiResponse
import io.swagger.v3.oas.annotations.responses.ApiResponses
import io.swagger.v3.oas.annotations.security.SecurityRequirement
import io.swagger.v3.oas.annotations.tags.Tag

@RestController
@RequestMapping("/api/v1/exam-papers")
@Tag(name = "试卷管理", description = "试卷信息管理和音频文件上传相关接口")
class ExamPaperController(
    private val examPaperService: ExamPaperService,
    private val weChatCloudStorageService: WeChatCloudStorageService
) {
    
    private val logger = LoggerFactory.getLogger(ExamPaperController::class.java)
    
    @Operation(
        summary = "获取试卷列表",
        description = "获取试卷列表，支持按年级筛选"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "获取成功")
    ])
    @GetMapping
    fun getExamPapers(
        @Parameter(description = "年级筛选（可选）") @RequestParam(required = false) grade: Int?,
        @Parameter(description = "试卷类型筛选（可选）") @RequestParam(required = false) type: String?
    ): ApiResponse<List<ExamPaper>> {
        logger.info("获取试卷列表，年级: $grade, 类型: $type")
        
        val examPapers = when {
            type != null -> {
                try {
                    val paperType = PaperType.valueOf(type.uppercase())
                    examPaperService.getExamPapersByType(paperType)
                } catch (_: IllegalArgumentException) {
                    return ApiResponse.error("无效的试卷类型: $type，支持的类型: PRACTICE, TEST")
                }
            }
            grade != null -> examPaperService.getExamPapersByGrade(grade)
            else -> examPaperService.getAllExamPapers()
        }
        
        return ApiResponse.ok("获取试卷列表成功", examPapers)
    }
    
    @Operation(
        summary = "获取试卷完整数据",
        description = "一次性获取试卷的所有模块数据，供前端缓存使用"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "获取成功"),
        SwaggerApiResponse(responseCode = "404", description = "试卷不存在")
    ])
    @GetMapping("/{id}")
    fun getExamPaperComplete(
        @Parameter(description = "试卷ID") @PathVariable id: Long
    ): ApiResponse<ExamPaperCompleteResponse> {
        logger.info("获取试卷完整数据: $id")
        
        val examPaper = examPaperService.getExamPaperById(id)
        return if (examPaper != null) {
            val response = ExamPaperCompleteResponse(
                id = examPaper.id!!,
                title = examPaper.title,
                targetGrade = examPaper.targetGrade,
                paperType = examPaper.paperType.name,
                createdTime = examPaper.createdTime,
                readingModule = ReadingModuleResponse(
                    content = examPaper.readingContent,
                    audioFileId = examPaper.readingAudioFileId
                ),
                listeningModule = ListeningModuleResponse(
                    questions = examPaper.listeningQuestions
                ),
                dialogueModule = DialogueModuleResponse(
                    questions = examPaper.dialogueQuestions
                ),
                topicModule = TopicModuleResponse(
                    topicBrief = examPaper.topicBrief,
                    keyPoints = if (examPaper.keyPoints.isNotEmpty()) {
                        examPaper.keyPoints.split("&").filter { it.isNotBlank() }
                    } else {
                        emptyList()
                    },
                    referenceAnswers = if (examPaper.referenceAnswers.isNotEmpty()) {
                        examPaper.referenceAnswers.split("&").filter { it.isNotBlank() }
                    } else {
                        emptyList()
                    }
                )
            )
            ApiResponse.ok("获取试卷完整数据成功", response)
        } else {
            ApiResponse.error("试卷不存在")
        }
    }
    
    @Operation(
        summary = "获取试卷原始数据（管理员）",
        description = "获取试卷完整原始数据，仅供管理后台使用"
    )
    @GetMapping("/{id}/raw")
    fun getExamPaperById(
        @Parameter(description = "试卷ID") @PathVariable id: Long
    ): ApiResponse<ExamPaper> {
        logger.info("获取试卷原始数据: $id")
        
        val examPaper = examPaperService.getExamPaperById(id)
        return if (examPaper != null) {
            ApiResponse.ok("获取试卷原始数据成功", examPaper)
        } else {
            ApiResponse.error("试卷不存在")
        }
    }
    
    @Operation(
        summary = "根据试卷类型获取试卷列表",
        description = "根据试卷类型（PRACTICE/TEST）获取试卷列表"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "获取成功"),
        SwaggerApiResponse(responseCode = "400", description = "无效的试卷类型")
    ])
    @GetMapping("/type/{type}")
    fun getExamPapersByType(
        @Parameter(description = "试卷类型 (PRACTICE/TEST)") @PathVariable type: String,
        @Parameter(description = "年级筛选（可选）") @RequestParam(required = false) grade: Int?
    ): ApiResponse<List<ExamPaper>> {
        logger.info("根据类型获取试卷列表: type=$type, grade=$grade")
        
        return try {
            val paperType = PaperType.valueOf(type.uppercase())
            val examPapers = if (grade != null) {
                // 先按类型获取，再按年级过滤
                examPaperService.getExamPapersByType(paperType).filter { it.targetGrade == grade }
            } else {
                examPaperService.getExamPapersByType(paperType)
            }
            ApiResponse.ok("获取试卷列表成功", examPapers)
        } catch (e: IllegalArgumentException) {
            ApiResponse.error("无效的试卷类型: $type，支持的类型: PRACTICE, TEST")
        }
    }
    
    @Operation(
        summary = "获取视听应答模块",
        description = "获取指定试卷的视听应答内容"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "获取成功"),
        SwaggerApiResponse(responseCode = "404", description = "试卷不存在")
    ])
    @GetMapping("/{id}/modules/listening")
    fun getListeningModule(
        @Parameter(description = "试卷ID") @PathVariable id: Long
    ): ApiResponse<ModuleResponse<ListeningModuleResponse>> {
        logger.info("获取视听应答模块: $id")
        
        val examPaper = examPaperService.getExamPaperById(id)
        return if (examPaper != null) {
            val listeningQuestions = examPaper.listeningQuestions
            val response = ModuleResponse(
                moduleType = ModuleType.LISTENING,
                data = ListeningModuleResponse(listeningQuestions),
                nextModule = ModuleType.LISTENING.next()
            )
            ApiResponse.ok("获取视听应答模块成功", response)
        } else {
            ApiResponse.error("试卷不存在")
        }
    }
    
    @Operation(
        summary = "获取情景对话模块",
        description = "获取指定试卷的情景对话内容"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "获取成功"),
        SwaggerApiResponse(responseCode = "404", description = "试卷不存在")
    ])
    @GetMapping("/{id}/modules/dialogue")
    fun getDialogueModule(
        @Parameter(description = "试卷ID") @PathVariable id: Long
    ): ApiResponse<ModuleResponse<DialogueModuleResponse>> {
        logger.info("获取情景对话模块: $id")
        
        val examPaper = examPaperService.getExamPaperById(id)
        return if (examPaper != null) {
            val dialogueQuestions = examPaper.dialogueQuestions
            val response = ModuleResponse(
                moduleType = ModuleType.DIALOGUE,
                data = DialogueModuleResponse(dialogueQuestions),
                nextModule = ModuleType.DIALOGUE.next()
            )
            ApiResponse.ok("获取情景对话模块成功", response)
        } else {
            ApiResponse.error("试卷不存在")
        }
    }
    
    @Operation(
        summary = "获取话题简述模块",
        description = "获取指定试卷的话题简述内容"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "获取成功"),
        SwaggerApiResponse(responseCode = "404", description = "试卷不存在")
    ])
    @GetMapping("/{id}/modules/topic")
    fun getTopicModule(
        @Parameter(description = "试卷ID") @PathVariable id: Long
    ): ApiResponse<ModuleResponse<TopicModuleResponse>> {
        logger.info("获取话题简述模块: $id")
        
        val examPaper = examPaperService.getExamPaperById(id)
        return if (examPaper != null) {
            val keyPoints = if (examPaper.keyPoints.isNotEmpty()) {
                examPaper.keyPoints.split("&").filter { it.isNotBlank() }
            } else {
                emptyList()
            }
            val referenceAnswers = if (examPaper.referenceAnswers.isNotEmpty()) {
                examPaper.referenceAnswers.split("&").filter { it.isNotBlank() }
            } else {
                emptyList()
            }
            
            val response = ModuleResponse(
                moduleType = ModuleType.TOPIC,
                data = TopicModuleResponse(
                    topicBrief = examPaper.topicBrief,
                    keyPoints = keyPoints,
                    referenceAnswers = referenceAnswers
                ),
                nextModule = ModuleType.TOPIC.next()
            )
            ApiResponse.ok("获取话题简述模块成功", response)
        } else {
            ApiResponse.error("试卷不存在")
        }
    }
    
    @Operation(
        summary = "批量获取模块",
        description = "一次性获取多个指定模块的内容"
    )
    @PostMapping("/{id}/modules/batch")
    fun getBatchModules(
        @Parameter(description = "试卷ID") @PathVariable id: Long,
        @RequestBody request: BatchModuleRequest
    ): ApiResponse<Map<String, Any>> {
        logger.info("批量获取模块: $id, 模块: ${request.modules}")
        
        val examPaper = examPaperService.getExamPaperById(id) 
            ?: return ApiResponse.error("试卷不存在")
        
        val result = mutableMapOf<String, Any>()
        
        request.modules.forEach { moduleType ->
            when (moduleType.uppercase()) {
                "LISTENING" -> {
                    val listeningQuestions = examPaper.listeningQuestions
                    result["listening"] = ModuleResponse(
                        moduleType = ModuleType.LISTENING,
                        data = ListeningModuleResponse(listeningQuestions),
                        nextModule = ModuleType.LISTENING.next()
                    )
                }
                "DIALOGUE" -> {
                    val dialogueQuestions = examPaper.dialogueQuestions
                    result["dialogue"] = ModuleResponse(
                        moduleType = ModuleType.DIALOGUE,
                        data = DialogueModuleResponse(dialogueQuestions),
                        nextModule = ModuleType.DIALOGUE.next()
                    )
                }
                "TOPIC" -> {
                    val keyPoints = if (examPaper.keyPoints.isNotEmpty()) {
                        examPaper.keyPoints.split("&").filter { it.isNotBlank() }
                    } else {
                        emptyList()
                    }
                    val referenceAnswers = if (examPaper.referenceAnswers.isNotEmpty()) {
                        examPaper.referenceAnswers.split("&").filter { it.isNotBlank() }
                    } else {
                        emptyList()
                    }
                    result["topic"] = ModuleResponse(
                        moduleType = ModuleType.TOPIC,
                        data = TopicModuleResponse(
                            topicBrief = examPaper.topicBrief,
                            keyPoints = keyPoints,
                            referenceAnswers = referenceAnswers
                        ),
                        nextModule = ModuleType.TOPIC.next()
                    )
                }
            }
        }
        
        return ApiResponse.ok("批量获取模块成功", result)
    }
    
    @Operation(
        summary = "上传音频文件",
        description = "上传音频文件到腾讯云COS存储"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "上传成功"),
        SwaggerApiResponse(responseCode = "400", description = "文件格式不支持或上传失败"),
        SwaggerApiResponse(responseCode = "401", description = "会话无效")
    ])
    @SecurityRequirement(name = "BearerAuth")
    @PostMapping("/upload-audio")
    fun uploadAudio(
        @Parameter(description = "音频文件") @RequestParam("file") file: MultipartFile
    ): ApiResponse<Map<String, Any?>> {
        val fileName = file.originalFilename ?: "audio.mp3"
        logger.info("上传音频文件: $fileName, 大小: ${file.size} bytes")
        
        // 验证文件类型
        if (!weChatCloudStorageService.isAudioFile(file)) {
            return ApiResponse.error("只支持音频文件格式")
        }
        
        // 验证文件大小
        if (!weChatCloudStorageService.isValidFileSize(file)) {
            return ApiResponse.error("文件大小不能超过10MB")
        }
        
        val uploadResult = weChatCloudStorageService.uploadAudioFile(file, fileName)
        
        return if (uploadResult.success) {
            val responseData: Map<String, Any?> = mapOf(
                "fileId" to uploadResult.fileId,
                "cosFileId" to uploadResult.cosFileId,
                "url" to uploadResult.url,
                "fileName" to fileName
            )
            ApiResponse.ok("音频文件上传成功", responseData)
        } else {
            ApiResponse.error(uploadResult.message)
        }
    }

    @Operation(
        summary = "上传图片文件",
        description = "上传图片文件到腾讯云COS"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "上传成功"),
        SwaggerApiResponse(responseCode = "400", description = "文件格式不支持或上传失败"),
        SwaggerApiResponse(responseCode = "401", description = "会话失效")
    ])
    @SecurityRequirement(name = "BearerAuth")
    @PostMapping("/upload-image")
    fun uploadImage(
        @Parameter(description = "图片文件") @RequestParam("file") file: MultipartFile
    ): ApiResponse<Map<String, Any?>> {
        val fileName = file.originalFilename ?: "image.png"
        logger.info("上传图片文件: $fileName, 大小: ${file.size} bytes")

        // 验证文件类型
        if (!weChatCloudStorageService.isImageFile(file)) {
            return ApiResponse.error("只支持图片文件格式")
        }
        // 验证文件大小
        if (!weChatCloudStorageService.isValidFileSize(file)) {
            return ApiResponse.error("文件大小不能超过10MB")
        }

        val uploadResult = weChatCloudStorageService.uploadImageFile(file, fileName)
        return if (uploadResult.success) {
            val responseData: Map<String, Any?> = mapOf(
                "fileId" to uploadResult.fileId,
                "cosFileId" to uploadResult.cosFileId,
                "url" to uploadResult.url,
                "fileName" to fileName
            )
            ApiResponse.ok("图片文件上传成功", responseData)
        } else {
            ApiResponse.error(uploadResult.message)
        }
    }
    
    @Operation(
        summary = "创建试卷",
        description = "创建新的试卷（管理员功能）"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "创建成功"),
        SwaggerApiResponse(responseCode = "400", description = "参数错误或创建失败"),
        SwaggerApiResponse(responseCode = "401", description = "会话无效")
    ])
    @SecurityRequirement(name = "SessionAuth")
    @PostMapping
    fun createExamPaper(@RequestBody examPaper: ExamPaper): ApiResponse<String> {
        logger.info("创建试卷: ${examPaper.title}")
        
        val success = examPaperService.createExamPaper(examPaper)
        return if (success) {
            ApiResponse.ok("试卷创建成功")
        } else {
            ApiResponse.error("试卷创建失败")
        }
    }
    
    @Operation(
        summary = "更新试卷",
        description = "更新指定试卷的信息（管理员功能）"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "更新成功"),
        SwaggerApiResponse(responseCode = "400", description = "参数错误或更新失败"),
        SwaggerApiResponse(responseCode = "401", description = "会话无效"),
        SwaggerApiResponse(responseCode = "404", description = "试卷不存在")
    ])
    @SecurityRequirement(name = "SessionAuth")
    @PutMapping("/{id}")
    fun updateExamPaper(
        @Parameter(description = "试卷ID") @PathVariable id: Long, 
        @RequestBody examPaper: ExamPaper
    ): ApiResponse<String> {
        logger.info("更新试卷: $id")
        
        val success = examPaperService.updateExamPaper(examPaper)
        return if (success) {
            ApiResponse.ok("试卷更新成功")
        } else {
            ApiResponse.error("试卷更新失败")
        }
    }
    
    @Operation(
        summary = "删除试卷",
        description = "删除指定的试卷（管理员功能）"
    )
    @ApiResponses(value = [
        SwaggerApiResponse(responseCode = "200", description = "删除成功"),
        SwaggerApiResponse(responseCode = "400", description = "删除失败"),
        SwaggerApiResponse(responseCode = "401", description = "会话无效"),
        SwaggerApiResponse(responseCode = "404", description = "试卷不存在")
    ])
    @SecurityRequirement(name = "SessionAuth")
    @DeleteMapping("/{id}")
    fun deleteExamPaper(
        @Parameter(description = "试卷ID") @PathVariable id: Long
    ): ApiResponse<String> {
        logger.info("删除试卷: $id")
        
        val success = examPaperService.deleteExamPaper(id)
        return if (success) {
            ApiResponse.ok("试卷删除成功")
        } else {
            ApiResponse.error("试卷删除失败")
        }
    }
}
